#include "Rect.h"
#include <glm/gtc/matrix_transform.hpp>

Rect::Rect()
{
	mPosition = glm::vec2(0.0f, 0.0f);
	mSize = glm::vec2(0.0f, 0.0f);
	mRect = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
	mCenter = glm::vec2(0.0f, 0.0f);
	mRadius = 0.0f;
	mAngle = 0.0f;
}

Rect::Rect(const glm::vec2& position, const glm::vec2& size)
{
	mPosition = position;
	mSize = size;
	mRect = glm::vec4(position.x, position.y, size.x, size.y);
	mCenter = position + size * 0.5f;
	mRadius = size.x * 0.5f;
	mAngle = 0.0f;
}

Rect::Rect(const glm::vec4& rect)
{
	mPosition = glm::vec2(rect.x, rect.y);
	mSize = glm::vec2(rect.z, rect.w);
	mRect = glm::vec4(rect.x, rect.y, rect.z, rect.w);
	mCenter = mPosition + mSize * 0.5f;
	mRadius = mSize.x * 0.5f;
	mAngle = 0.0f;
}

Rect::Rect(float x, float y, float width, float height)
{
	mPosition = glm::vec2(x, y);
	mSize = glm::vec2(width, height);
	mRect = glm::vec4(x, y, width, height);
	mCenter = mPosition + mSize * 0.5f;
	mRadius = mSize.x * 0.5f;
	mAngle = 0.0f;
}

const glm::vec2& Rect::GetPosition() const
{
	return mPosition;
}
const glm::vec2& Rect::GetSize() const
{
	return mSize;
}

const glm::vec4& Rect::Get() const
{
	return mRect;
}

void Rect::SetPosition(const glm::vec2& position)
{
	mPosition = position;
	mRect.x = position.x;
	mRect.y = position.y;
	mCenter = mPosition + mSize * 0.5f;
}

void Rect::SetSize(const glm::vec2& size)
{
	mSize = size;
	mRect.z = size.x;
	mRect.w = size.y;
	mCenter = mPosition + mSize * 0.5f;
	mRadius = mSize.x * 0.5f;
}

void Rect::Set(const glm::vec2& position, const glm::vec2& size)
{
	mPosition = position;
	mSize = size;
	mRect.x = position.x;
	mRect.y = position.y;
	mRect.z = size.x;
	mRect.w = size.y;
	mCenter = mPosition + mSize * 0.5f;
	mRadius = mSize.x * 0.5f;
}

void Rect::Set(float x, float y, float width, float height)
{
	mPosition = glm::vec2(x, y);
	mSize = glm::vec2(width, height);
	mRect.x = x;
	mRect.y = y;
	mRect.z = width;
	mRect.w = height;
	mCenter = mPosition + mSize * 0.5f;
	mRadius = mSize.x * 0.5f;
}

void Rect::Transform(const glm::mat4& transform)
{
	mRect = transform * mRect;
	mPosition = glm::vec2(mRect.x, mRect.y);
	mSize = glm::vec2(mRect.z, mRect.w);
	mCenter = mPosition + mSize * 0.5f;
	mRadius = mSize.x * 0.5f;
}

void Rect::SetCenter(const glm::vec2& center)
{
	mPosition = center - mSize * 0.5f;
	mRect.x = center.x - mSize.x * 0.5f;
	mRect.y = center.y - mSize.y * 0.5f;
	mCenter = center;
}

void Rect::SetCenter(float x, float y)
{
	mPosition.x = x - mSize.x * 0.5f;
	mPosition.y = y - mSize.y * 0.5f;
	mRect.x = x - mSize.x * 0.5f;
	mRect.y = y - mSize.y * 0.5f;
	mCenter.x = x;
	mCenter.y = y;
}

bool Rect::IsInside(const glm::vec2& point) const
{
	if (point.x < mPosition.x || point.x > mPosition.x + mSize.x)
	{
		return false;
	}

	if (point.y < mPosition.y || point.y > mPosition.y + mSize.y)
	{
		return false;
	}

	return true;
}

bool Rect::IsInside(float x, float y) const
{
	if (x < mPosition.x || x > mPosition.x + mSize.x)
	{
		return false;
	}

	if (y < mPosition.y || y > mPosition.y + mSize.y)
	{
		return false;
	}

	return true;
}

bool Rect::IsInside(const Rect& rect) const
{
	if (rect.mPosition.x > mPosition.x + mSize.x || rect.mPosition.x + rect.mSize.x < mPosition.x)
	{
		return false;
	}

	if (rect.mPosition.y > mPosition.y + mSize.y || rect.mPosition.y + rect.mSize.y < mPosition.y)
	{
		return false;
	}

	return true;
}

bool Rect::Intersects(const Rect& rect) const
{
	if (rect.mPosition.x > mPosition.x + mSize.x || rect.mPosition.x + rect.mSize.x < mPosition.x)
	{
		return false;
	}

	if (rect.mPosition.y > mPosition.y + mSize.y || rect.mPosition.y + rect.mSize.y < mPosition.y)
	{
		return false;
	}

	return true;
}
